//
//  BaseJSONService.m
//  EPTool
//
//  Created by guoshiqing on 2018/4/9.
//  Copyright © 2018年 云数动能科技. All rights reserved.
//

#import "BaseJSONService.h"
#import "Macro.h"
#import "CommonHelper.h"
#import "sys/utsname.h"
#import "StringUtil.h"
#import "UserSettings.h"

@implementation BaseJSONService
#pragma mark - 设置url
- (NSString *)serviceBaseUrl
{
#ifdef DEBUG
    NSLog(@"%@", UserSaveInfo.serverUrl);
#endif
    return UserSaveInfo.serverUrl;
}


+ (instancetype)share
{
    static BaseJSONService *service;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        service = [[BaseJSONService alloc] init];
    });
    return service;
}


/**
 监测网络的可链接性
 @return 是否可达
 */
+ (BOOL)netWorkReachability{
    __block BOOL netState = YES;
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusNotReachable:
            case AFNetworkReachabilityStatusUnknown:
                netState = NO;
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
            case AFNetworkReachabilityStatusReachableViaWWAN:
                netState = YES;
                break;
                
            default:
                break;
        }
        NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));
    }];
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    return netState;
}


//////////////////////////////// https + json ////////////////////////////////
/**
 支持JSON的POST方法请求:JSON请求入参为NSDictionary, 返回是NSData
 
 @param url         请求地址
 @param parameters  参数列表（字典）
 @param success     成功返回
 @param failure     失败返回
 */
- (void)postMethodSupportJSONWithUrl:(NSString *)url
                          parameters:(nullable NSDictionary *)parameters
                             success:(void(^)(id data))success
                               error:(void(^)(NSError *err))error
                             failure:(void(^)(void))failure
{
    if (![[self class] netWorkReachability]) {
        failure();
    }
    
    [self requestWithMethod:@"POST" withURL:[self packUrl:[NSString stringWithFormat:@"%@%@",[self serviceBaseUrl],url] params:nil] parameters:parameters success:^(NSData *result) {
        success(result);
    } failure:^(NSError *err) {
        error(err);
    }];
}

- (void)getMethodSupportJSONWithUrl:(NSString *)url
                         parameters:(NSDictionary *)parameters
                            success:(void(^)(id data))success
                              error:(void(^)(NSError *err))error
                            failure:(void(^)(void))failure
{
    if (![[self class] netWorkReachability]) {
        failure();
    }
    [self requestWithMethod:@"GET" withURL:url parameters:parameters success:^(NSData *result) {
        
        success(result);
    } failure:^(NSError *err) {
        error(err);
    }];
}


/**
 http请求通用方法（私有对象方法，不对外）
 
 @param method 方法名称："GET"/"POST"
 @param url url路径
 @param parameters 放入body的nsdata数据
 @param success 成功返回
 @param failure 失败返回
 */
- (void)requestWithMethod:(NSString *)method withURL:(NSString *)url parameters:(NSDictionary *)parameters success:(void(^)(NSData *result))success failure:(void(^)(NSError *err))failure
{
    // 子类定制头部
    [self setHttpHead];
    
    if ([method isEqualToString:@"GET"])
    {
        [self GET:url parameters:parameters success:success failure:failure];
    }else if ([method isEqualToString:@"POST"])
    {
        [self POST:url parameters:parameters success:success failure:failure];
    }
}

- (void)GET:(NSString *)url parameters:(id)parameters success:(void(^)(NSData *result))success failure:(void(^)(NSError *err))failure
{
    [self.manager GET:url parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
         // 进度
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        success(responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull err) {
        failure(err);
    }];
}

- (void)POST:(NSString *)url parameters:(id)parameters success:(void(^)(NSData *result))success failure:(void(^)(NSError *err))failure
{
#ifdef EPToolDevelopmentVersion
    NSLog(@"\n\n请求url %@\n", url);
#endif
    [self.manager POST:url parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
        // 进度
    } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
        success(responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull err) {
        failure(err);
    }];
}

- (AFHTTPSessionManager *)manager
{
    if (!_manager || 0 == UserSaveInfo.token.length) {
        
        _manager = [[AFHTTPSessionManager manager] initWithBaseURL:nil sessionConfiguration:[self setProxyWithConfig]];
        
        _manager.responseSerializer = [AFJSONResponseSerializer serializer];
        _manager.requestSerializer = [AFJSONRequestSerializer serializer];

//        NSString *contentType = @"application/json";
//        [_manager.requestSerializer setValue:contentType forHTTPHeaderField:@"Content-Type"];
//        [_manager.requestSerializer setValue:contentType forHTTPHeaderField:@"Accept"];
//        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:contentType,@"text/html", nil];
//
//        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
//        [securityPolicy setAllowInvalidCertificates:YES];
//        [securityPolicy setValidatesDomainName:NO];
//        _manager.securityPolicy = securityPolicy;
        
        // 设置超时时间
        [_manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
        _manager.requestSerializer.timeoutInterval = 10.f;
        [_manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
        
        // 设置版本号
        [_manager.requestSerializer setValue:BundleVersion forHTTPHeaderField:@"version"];
        // 设置系统
        [_manager.requestSerializer setValue:@"ios" forHTTPHeaderField:@"d-os"];
    }
    
    // 头部有token才设置token
    NSString *tokenKey = @"d-tk";
    NSString *token = [_manager.requestSerializer valueForHTTPHeaderField:tokenKey];
//    NSLog(@"saveToken=%@, headToken=%@", UserSaveInfo.token, token);
    if (![UserSaveInfo.token isEqualToString:token]) {
        [_manager.requestSerializer setValue:UserSaveInfo.token forHTTPHeaderField:tokenKey];
    }
    
    // 头部有语言版本
    NSString *langKey = @"lang";
    NSUserDefaults *defaultUser = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaultUser objectForKey:@"AppleLanguages"];
    NSString *preferredLang = [languages objectAtIndex:0];
    BOOL isContain = [StringUtil containString:@"zh-Hant" inString:preferredLang ignoreCase:NO];
    if (isContain)
    {
        preferredLang = @"TW";
    }
    else
    {
        preferredLang = @"CN";
    }
    NSString *lang = [_manager.requestSerializer valueForHTTPHeaderField:langKey];
    if (![preferredLang isEqualToString:lang]) {
        [_manager.requestSerializer setValue:preferredLang forHTTPHeaderField:langKey];
    }
    
    // 当前设备类型
    NSString *phoneModelKey = @"DeviceModel";
    NSString *preferredPhoneModel =  [self deviceVersion];
    NSString *phoneModel = [_manager.requestSerializer valueForHTTPHeaderField:phoneModelKey];
    if (![preferredPhoneModel isEqualToString:phoneModel]) {
        [_manager.requestSerializer setValue:preferredPhoneModel forHTTPHeaderField:phoneModelKey];
    }
    
    // 头部添加当前团队teamid
    NSString *teamIdKey = @"iTeamId";
    NSString *teamId = [_manager.requestSerializer valueForHTTPHeaderField:teamIdKey];
    // 优先使用外部传递的teamid
    NSString *cureentTeamId = self.strTeamId;
    if (!cureentTeamId || 0 == cureentTeamId.length) {
        cureentTeamId = [CommonHelper shared].team.iTeamId;
    }
    if (cureentTeamId && ![cureentTeamId isEqualToString:teamId]) {
        [_manager.requestSerializer setValue:cureentTeamId forHTTPHeaderField:teamIdKey];
    }
    
    return _manager;
}

#pragma mark - 设置代理
- (NSURLSessionConfiguration *)setProxyWithConfig
{
    return nil;
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    config.connectionProxyDictionary = @
    {
        @"HTTPEnable":@YES,
        (__bridge NSString*)kCFStreamPropertyHTTPProxyHost:@"39.108.138.194",
        (__bridge NSString*)kCFStreamPropertyHTTPProxyPort:@443,
        @"HTTPSEnable":@YES,
        (__bridge NSString*)kCFStreamPropertyHTTPSProxyHost:@"39.108.138.194",
        (__bridge NSString*)kCFStreamPropertyHTTPSProxyPort:@443
    };
    return config;
}

#pragma mark - 设置头部，由子类实现
- (void)setHttpHead
{
    NSLog(@"Subclasses implement");
}

#pragma mark - url上拼接参数列表的信息，该函数后面需要废弃，所有参数非特殊情况都不能拼接到URL中
- (NSString *)packUrl:(NSString *)url params:(NSDictionary *)params{
    NSMutableString *finalUrl = [NSMutableString stringWithString:url];
    
    if (nil == finalUrl || 0 == finalUrl.length) {
        return nil;
    }
    
    //拼接上参数：
    if (params && params.count > 0) {
        //检查是否带?
        NSRange range = [finalUrl rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"?"]];
        if (range.location == NSNotFound) {
            [finalUrl appendString:@"?"];
        }
        else
        {
            [finalUrl appendString:@"&"];
        }
        
        NSArray *keys = params.allKeys;
        for (int i=0; i<keys.count; i++) {
            NSString *key = keys[i];
            NSString *value = [params objectForKey:key];
            
            NSString *s = [NSString stringWithFormat:@"%@=%@", [self urlEncoding:key], [self urlEncoding:value]];
            
            [finalUrl appendString:s];
            
            //不是最后一个，则加上&
            if (i < keys.count-1) {
                [finalUrl appendString:@"&"];
            }
        }
    }
    return finalUrl;
}

- (NSString *)urlEncoding:(NSString *)string {
    if (string == nil) {
        return @"";
    }
    
    NSString *s = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
                                                                                        (__bridge CFStringRef)string,
                                                                                        NULL,
                                                                                        (__bridge CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                                                        kCFStringEncodingUTF8));
    
    return s;
}



- (NSString*)deviceVersion
{
    // 需要#import "sys/utsname.h"
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString * deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    //iPhone
    if ([deviceString isEqualToString:@"iPhone3,1"])    return @"iPhone 4";
    if ([deviceString isEqualToString:@"iPhone3,2"])    return @"iPhone 4";
    if ([deviceString isEqualToString:@"iPhone3,3"])    return @"iPhone 4";
    if ([deviceString isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
    if ([deviceString isEqualToString:@"iPhone5,1"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone5,2"])    return @"iPhone 5 (GSM+CDMA)";
    if ([deviceString isEqualToString:@"iPhone5,3"])    return @"iPhone 5C (GSM)";
    if ([deviceString isEqualToString:@"iPhone5,4"])    return @"iPhone 5C (GSM+CDMA)";
    if ([deviceString isEqualToString:@"iPhone6,1"])    return @"iPhone 5S (GSM)";
    if ([deviceString isEqualToString:@"iPhone6,2"])    return @"iPhone 5S (GSM+CDMA)";
    if ([deviceString isEqualToString:@"iPhone7,1"])    return @"iPhone 6 Plus";
    if ([deviceString isEqualToString:@"iPhone7,2"])    return @"iPhone 6";
    if ([deviceString isEqualToString:@"iPhone8,1"])    return @"iPhone 6s";
    if ([deviceString isEqualToString:@"iPhone8,2"])    return @"iPhone 6s Plus";
    if ([deviceString isEqualToString:@"iPhone8,4"])    return @"iPhone SE";
    // 日行两款手机型号均为日本独占，可能使用索尼FeliCa支付方案而不是苹果支付
    if ([deviceString isEqualToString:@"iPhone9,1"])    return @"iPhone 7";
    if ([deviceString isEqualToString:@"iPhone9,2"])    return @"iPhone 7 Plus";
    if ([deviceString isEqualToString:@"iPhone9,3"])    return @"iPhone 7";
    if ([deviceString isEqualToString:@"iPhone9,4"])    return @"iPhone 7 Plus";
    if ([deviceString isEqualToString:@"iPhone10,1"])   return @"iPhone 8";
    if ([deviceString isEqualToString:@"iPhone10,4"])   return @"iPhone 8";
    if ([deviceString isEqualToString:@"iPhone10,2"])   return @"iPhone 8 Plus";
    if ([deviceString isEqualToString:@"iPhone10,5"])   return @"iPhone 8 Plus";
    if ([deviceString isEqualToString:@"iPhone10,3"])   return @"iPhone X";
    if ([deviceString isEqualToString:@"iPhone10,6"])   return @"iPhone X";
    if ([deviceString isEqualToString:@"i386"])         return @"Simulator";
    if ([deviceString isEqualToString:@"x86_64"])       return @"Simulator";
    return deviceString;
}
@end
